//========================================================================
//  This software is free: you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License Version 3,
//  as published by the Free Software Foundation.
//
//  This software is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public License
//  Version 3 in the file COPYING that came with this distribution.
//  If not, see <http://www.gnu.org/licenses/>.
//========================================================================
/*!
\file    kinect_wrapper.cpp
\brief   C++ Declaration: KinectWrapper
\author  Joydeep Biswas, (C) 2011
*/
//========================================================================

#include <stdio.h>
#ifdef _WIN32
// MS Kinect SDK exists only for Windows
#include <windows.h>
#include "MSR_NuiApi.h"
#include "MSRKinectAudio.h"
#include "MSR_NuiImageCamera.h"
#include "MSR_NuiProps.h"
#include "MSR_NuiSkeleton.h"
#include "MSRKinectAudio.h"
#include "NuiImageBuffer.h"
#else
// Emulate non-functional Kinect SDK on other platforms
#include "kinect_stubs.h"
#endif

#ifndef KINECT_WRAPPER_H
#define KINECT_WRAPPER_H

class KinectWrapper{
  static const bool debug = true;

  ///Indicates that depth image stream is being read
  bool getDepthImg; 
  ///Indicates that labeled (player ID) depth image stream is being read
  bool getLabeledDepthImg;
  ///Indicates that skeleton data
  bool getSkeletonData;
  ///Indicates that RGB image stream is being read
  bool getRGBImg;

  ///Callback function to call when depth image is available
  void (*depthCallback)(BYTE*);
  ///Callback function to call when labeled depth image is available
  void (*labeledDepthCallback)(BYTE*);
  ///Callback function to call when skeleton data is available
  void (*skeletonCallback)(NUI_SKELETON_FRAME*);
  ///Callback function to call when RGB image is available
  void (*rgbCallback)(BYTE*);

  ///Handle to depth image stream
  HANDLE hDepthStream;
  ///Handle to labelled depth image stream
  HANDLE hLabeledDepthStream;
  ///Handle to RGB image stream
  HANDLE hRGBStream;
  ///Event object to notify availability of depth image
  HANDLE m_hNextDepthFrameEvent;
  ///Event object to notify availability of labeled depth image
  HANDLE m_hNextLabeledDepthFrameEvent;
  ///Event object to notify availability of RGB image
  HANDLE m_hNextVideoFrameEvent;

  NUI_SKELETON_FRAME SkeletonFrame;

  void errorInfo(HRESULT error);

public:
  KinectWrapper();
  ~KinectWrapper();
  int connect(  void (*_depthCallback)(BYTE*), 
                void (*_labeledDepthCallback)(BYTE*),
                void (*_skeletonCallback)(NUI_SKELETON_FRAME*),
                void (*_rgbCallback)(BYTE*));
  void close();
  void poll();
};

#endif //KINECT_WRAPPER_H